package com.techfork.hutool.teck;

import java.util.Iterator;

/**
 * 位运算
 */
public class TestBit {

    public static void main(String[] args) {
        testBit00();

    }

    public static void testBit00() {
        System.out.println(-1L >>> 1);
        testBit0(-1L);
        testBit0(-1L >>> 1);
        // -1L>>>n 可以保留多少个 1
        testBit0(~(-1L >>> -2));
        testBit0((-1L >>> -2));
    }

    public static void testBit0(long var0) {
        var0 -= var0 >>> 1 & 6148914691236517205L;
        var0 = (var0 & 3689348814741910323L) + (var0 >>> 2 & 3689348814741910323L);
        var0 = var0 + (var0 >>> 4) & 1085102592571150095L;
        var0 += var0 >>> 8;
        var0 += var0 >>> 16;
        var0 += var0 >>> 32;
        System.out.println((int) var0 & 127);
    }

    public static void testBit(int n) {
        int res = n;
        while (n > 0) {
            res -= (n >>>= 1);
        }
        System.out.println(res);

        // 并行, 分组计算
        /*
        0b1111 1111 = (8e+4f+2g+h)*16 + (8a+4b+2c+d) => e+f+g+h + a+b+c+d
        0b1111 1111>>>1 & 0b0111 0111 = (4e+2f+g)*16 + (4a+2b+c)
        0b1111 1111>>>2 & 0b0111 0111 = (2e+f)*16 + (2a+b)
        0b1111 1111>>>3 & 0b0111 0111 = (e)*16 + (a)
        => X=Y=(e+f+g+h)*16 + a+b+c+d）
        => X>>>4 + Y&0b1111
        => e+f+g+h + a+b+c+d
         */
        // 两位一组
        /*
        111100001111000011110000111100001111000011110000111100001111
            ORG = 0b11 11 11 11 = (2e+f)*64 + (2g+h)*16 + (2a+b)*4 + (2c+d) => e+f + g+h + a+b + c+d
            0b11 11 11 11>>>1 & 0b01 01 01 01 = (e)*64 + (g)*16 + (a)*4 + (c+d)
            => X = (e)*64 + (g)*16 + (a)*4 + (c)
            => A=B=C=D = ORG - X = (e+f)*64 + (g+h)*16 + (a+b)*4 + (c+d)
            => A>>>4 + (B>>>3 & 0b11) + (C>>>2 & 0b11) + D
            => e+f+g+h + a+b+ c+d

         */
        // 先分后合
        /*
        ORG =
0b11 11 11 11 = (2e+f)*64 + (2g+h)*16 + (2a+b)*4 + (2c+d) => e+f + g+h + a+b + c+d
0b11 11 11 11>>>1 & 0b01 01 01 01 = (e)*64 + (g)*16 + (a)*4 + (c)

=> X = (e)*64 + (g)*16 + (a)*4 + (c)
=> A = ORG - X = (e+f)*64 + (g+h)*16 + (a+b)*4 + (c+d)
=> B = (A>>>2 & 0b00110011)  + (A & 0b00110011) = (e+f+g+h)*16 + (a+b+c+d)
=> B>>>4 + B = (e+f+g+h+a+b+c+d)
// 随着位数增加，需要用二分合并
// 分成16组，每组4bit
K = A1-4 A5-8 A9-12 A13-16 A17-20 A21-24 A25-28 A29-32 A33-36 A37-40 A41-44 A45-48 A49-52 A53-56 A57-60 A61-64
P = K>>>4 & 000 1111...000 1111//与操作主要是造成进位空洞，防止超过限制
=>       A1-4 A5-8  A9-12  A13-16 A17-20 A21-24 A25-28 A29-32 A33-36 A37-40 A41-44 A45-48 A49-52 A53-56 A57-60 //A1-64
=>       A1-4       A9-12         A17-20        A25-28        A33-36        A41-44        A49-52        A57-60
K8 = K + P
=>       A1-8       A9-16         A17-24        A25-32        A33-40        A41-48        A49-56        A57-64
P8 = K8>>>8
=>                  A1-8          A9-16         A17-24        A25-32        A33-40        A41-48        A49-56   //A57-64
K16 = K8 + P8
=>                  A1-16                       A17-32                      A33-48                      A49-64
P16 = K16>>>16
=>                                A1-16                       A17-32                      A33-48                 //A49-64
K32 = K16 + P16
=>                                              A1-32                                                   A33-64
P32 = K32>>>32
=>                                                                                                      A1-64


         */
    }
}
